/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2019-03-08     obito0   first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "gui_c.h"
#include "button.h"

#include "ttl433.h"



#define DBG_ENABLE
#define DBG_SECTION_NAME               "MAIN"
#ifdef WEBCLIENT_DEBUG
#define DBG_LEVEL                      DBG_LOG
#else
#define DBG_LEVEL                      DBG_LOG
#endif /* WEBCLIENT_DEBUG */
#define DBG_COLOR
#include <rtdbg.h>

rt_uint8_t enble_sys_led = 1;

#define LED0_PIN    GET_PIN(C, 13)
#define SHOW_PIN		GET_PIN(C, 0)
#define ADC_DEV_NAME        "adc1"  /* ADC 设备名称 */
#define ADC_DEV_CHANNEL     11       /* ADC 通道 */
//char Str[64];
rt_mutex_t battery_mutex = RT_NULL;  
rt_adc_device_t  adc1 = RT_NULL;
float adc_v = 0;//电源电压值
rt_thread_t Key_th=RT_NULL;
static rt_sem_t show_sem = RT_NULL;
void Key_entry(void * arg)
{
	static rt_err_t result;
	while(1)
	{
		if(show_sem)
		{
			result = rt_sem_take(show_sem, 20);
			if(result == RT_EOK)
			{
				Gui_CloseShow();
				enble_sys_led = 0;//关闭系统状态灯
				rt_pin_write(LED0_PIN, PIN_HIGH);
			}
		}
		else
			rt_thread_mdelay(20);
		Button_Process();
	}
}
rt_timer_t timer_close_show = RT_NULL;
Button_t show_bnt;
void show_bnt_Dowm_CallBack(void *btn) {
	enble_sys_led = 1;
	Gui_OpenShow();
	if(timer_close_show)
		rt_timer_start(timer_close_show);
}
uint8_t Read_show_bnt(void) { 
	return rt_pin_read(SHOW_PIN); 
}
static void timer_close_show_fun(void *parameter)
{
	//LOG_I("定时器");
	if(show_sem)
		rt_sem_release(show_sem);
}
int main(void)
{	
	rt_uint8_t battery = 100;
	
	
	Key_th=rt_thread_create("Key_th",Key_entry,RT_NULL,512
	,10,20);
	
	if(Key_th	)
		rt_thread_startup(	Key_th);
	else
		LOG_E("Key_th thread Error\r\n");
	
		rt_pin_mode(SHOW_PIN,PIN_MODE_INPUT_PULLUP);
	
	Button_Create("send_bnt",                //按键名字
             &show_bnt,                 //按键句柄
             Read_show_bnt,     //按键电平检测函数接口
             0); 
	Button_Attach(&show_bnt,BUTTON_DOWM,show_bnt_Dowm_CallBack);
	timer_close_show = rt_timer_create("show", timer_close_show_fun,
                             RT_NULL,  10000,
                             RT_TIMER_FLAG_ONE_SHOT|RT_TIMER_FLAG_SOFT_TIMER);
	if(timer_close_show)
		rt_timer_start(timer_close_show);
	show_sem = rt_sem_create("show_sem", 0, RT_IPC_FLAG_FIFO);
	
	Gui_Msg_t Battery_msg = rt_malloc( sizeof(struct Gui_Msg));
	
	battery_mutex = rt_mutex_create ("battery_mutex", RT_IPC_FLAG_FIFO);
	adc1 = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
	if(adc1)
		rt_adc_enable(adc1,ADC_DEV_CHANNEL);
	while(1)
	{
		rt_thread_mdelay(1000);
		
		
/*******获取电量*****/
		//获取AD值
		if(adc1)
		{
			rt_uint32_t adc_value;
			adc_value = rt_adc_read(adc1,ADC_DEV_CHANNEL);
			//保护资源
			if(battery_mutex)
				rt_mutex_take (battery_mutex, -1);
			adc_v = adc_value * (3.28/4096.0) * 2 + 0.2;
			if(battery_mutex)
				rt_mutex_release(battery_mutex);
			
//具体数据如下,以10%的容量间隔进行划分

//ocv电压对容量关系 550ma恒流放电电压对容量关系

//100%----4.20v 100%----4.20v

//90%-----4.06v 90%-----3.97v

//80%-----3.98v 80%-----3.87v

//70%-----3.92v 70%-----3.79v▲

//60%-----3.87v 60%-----3.73v

//50%-----3.82v 50%-----3.68v

//40%-----3.79v▲ 40%-----3.65v

//30%-----3.77v 30%-----3.62v

//20%-----3.74v 20%-----3.58v

//10%-----3.68v 10%-----3.51v

//5%------3.45v 5%------3.42v

//0%------3.00v 0%------3.00v
			if(adc_v > 4.13)
				battery = 100;
			else if(adc_v >= 4.06)
				battery = 95;
			else if(adc_v >= 3.98)
				battery = 85;
			else if(adc_v >= 3.92)
				battery = 75;	
			else if(adc_v >= 3.87)
				battery = 65;
			else if(adc_v >= 3.82)
				battery = 55;
			else if(adc_v >= 3.79)
				battery = 45;
			else if(adc_v >= 3.77)
				battery = 35;
			else if(adc_v >= 3.74)
				battery = 25;
			else if(adc_v >= 3.68)
				battery = 15;
			else if(adc_v >= 3.45)
				battery = 10;
			else// <3.0 
				battery = 0;
			//battery = (adc_v/6.0)*100;
//			if(battery > 100)
//				battery = 100;
			//sprintf(Str,"电源电压:%.2f\r\n",adc_v);
			//rt_kprintf(Str);
		}
		
		//发送电量信息
		Gui_BatteryStat(GUI_BATTERY_STAT_DISCHARGING,battery);
	
	if(Battery_msg)
	{
		Battery_msg->type = GUI_MSG_TEPY_SHOW_BATERY;
		Battery_msg->data.float_msg = adc_v;
		Gui_SendMsg(Battery_msg);
	}
/*****************/
	}
}
float GetBatteryV()
{
	float rec;
	if(battery_mutex)
		rt_mutex_take (battery_mutex, -1);
	rec = adc_v;
	if(battery_mutex)
		rt_mutex_release(battery_mutex);
	return rec;
}
static void led_hook(void)
{
				static uint32_t cnt =0;
				if(cnt == 0)
					if(enble_sys_led)
						rt_pin_write(LED0_PIN, PIN_LOW);
				if(cnt == 50000)
					if(enble_sys_led)
						rt_pin_write(LED0_PIN, PIN_HIGH);
				cnt++;
				if(cnt == 70000)
					cnt = 0;
        
}
int sys_stat_led_init(void)
{
	rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
	rt_pin_write(LED0_PIN, PIN_HIGH);
	return rt_thread_idle_sethook(led_hook);
}
INIT_APP_EXPORT(sys_stat_led_init);
#define IWDG_DEVICE_NAME    "wdt"    /* 看门狗设备名称 */

static rt_device_t wdg_dev;         /* 看门狗设备句柄 */

static void idle_hook(void)
{
    /* 在空闲线程的回调函数里喂狗 */
    rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
    //rt_kprintf("feed the dog!\n ");
}

static int iwdg_init()
{
    rt_err_t ret = RT_EOK;
    rt_uint32_t timeout = 5;        
    
    /* 根据设备名称查找看门狗设备，获取设备句柄 */
    wdg_dev = rt_device_find(IWDG_DEVICE_NAME);
    if (!wdg_dev)
    {
        rt_kprintf("find %s failed!\n", IWDG_DEVICE_NAME);
        return RT_ERROR;
    }
    /* 初始化设备 */
    ret = rt_device_init(wdg_dev);
    if (ret != RT_EOK)
    {
        rt_kprintf("initialize %s failed!\n", IWDG_DEVICE_NAME);
        return RT_ERROR;
    }
    /* 设置看门狗溢出时间 */
    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
    if (ret != RT_EOK)
    {
        rt_kprintf("set %s timeout failed!\n", IWDG_DEVICE_NAME);
        return RT_ERROR;
    }
		/* 启动看门狗 */
    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);
    if (ret != RT_EOK)
    {
        rt_kprintf("start %s failed!\n", IWDG_DEVICE_NAME);
        return -RT_ERROR;
    }
    /* 设置空闲线程回调函数 */
    rt_thread_idle_sethook(idle_hook);

    return ret;
}
INIT_APP_EXPORT(iwdg_init);

